// Fill out your copyright notice in the Description page of Project Settings.


#include "Character/EnemyCharacter.h"

#include "AbilitySystem/AuraAbilitySystemBPLibrary.h"
#include "AbilitySystem/AuraAbilitySystemComponent.h"
#include "AbilitySystem/AuraAttributeSet.h"
#include "AI/AuraAIController.h"
#include "Aura/Aura.h"
#include "BehaviorTree/BehaviorTree.h"
#include "BehaviorTree/BlackboardComponent.h"
#include "Components/WidgetComponent.h"
#include "Game/AuraGameplayTags.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "UI/Widget/AuraUserWidget.h"


AEnemyCharacter::AEnemyCharacter()
{
	// 不在面板显示不使用的父类属性
	bShowProps = false;

	bUseControllerRotationPitch = false;
	bUseControllerRotationYaw = false;
	bUseControllerRotationRoll = false;

	AbilitySystemComponent = CreateDefaultSubobject<UAuraAbilitySystemComponent>(TEXT("AbilitySystemComponent"));
	AttributeSet = CreateDefaultSubobject<UAuraAttributeSet>(TEXT("AttributeSet"));
	HealthBar = CreateDefaultSubobject<UWidgetComponent>(TEXT("HealthBar"));
	HealthBar->SetupAttachment(GetRootComponent());

	// 设置能力系统组件的复制状态
	AbilitySystemComponent->SetIsReplicated(true);
	AbilitySystemComponent->SetReplicationMode(EGameplayEffectReplicationMode::Minimal);

	GetMesh()->SetCollisionResponseToChannel(ECC_Visibility, ECR_Block);
}

void AEnemyCharacter::PossessedBy(AController* NewController)
{
	Super::PossessedBy(NewController);

	if (!HasAuthority())
	{
		return;
	}

	AuraAIController = Cast<AAuraAIController>(NewController);
	AuraAIController->GetBlackboardComponent()->InitializeBlackboard(*BehaviorTree->BlackboardAsset);
	AuraAIController->RunBehaviorTree(BehaviorTree);

	// ----------------------------------------------------------------------------------------------------------------
	//	设置黑板键的值
	// ----------------------------------------------------------------------------------------------------------------

	AuraAIController->GetBlackboardComponent()->SetValueAsBool(TEXT("HitReacting"), false);
	// 设置是否为远程攻击角色
	AuraAIController->GetBlackboardComponent()->SetValueAsBool(
		TEXT("RangedAttacker"),
		RoleClass != ERoleClass::Warrior
	);
}

void AEnemyCharacter::ShouldHighlightActor(const bool bHighlight)
{
	if (bHighlight)
	{
		GetMesh()->SetRenderCustomDepth(true);
		GetMesh()->SetCustomDepthStencilValue(CUSTOM_DEPTH_RED);
		Weapon->SetRenderCustomDepth(true);
		Weapon->SetCustomDepthStencilValue(CUSTOM_DEPTH_RED);
	}
	else
	{
		GetMesh()->SetRenderCustomDepth(false);
		Weapon->SetRenderCustomDepth(false);
	}
}


void AEnemyCharacter::Die()
{
	// 设置角色的生命周期
	SetLifeSpan(LifePan);

	if (AuraAIController)
	{
		// 设置状态为死亡，停止AI行为树
		AuraAIController->GetBlackboardComponent()->SetValueAsBool(FName("Dead"), true);
	}
	Super::Die();
}

AActor* AEnemyCharacter::GetCombatTarget_Implementation() const
{
	return CombatTarget;
}

void AEnemyCharacter::SetCombatTarget_Implementation(AActor* InCombatTarget)
{
	CombatTarget = InCombatTarget;
}


void AEnemyCharacter::BeginPlay()
{
	Super::BeginPlay();

	//设置角色的初始移动速度
	GetCharacterMovement()->MaxWalkSpeed = BaseWalkSpeed;

	// 初始化ASC相关信息
	InitAbilityActorInfo();
	
	// 在服务器给角色的ASC初始化起始能力
	if (HasAuthority())
	{
		UAuraAbilitySystemBPLibrary::GiveStartupAbilities(this, AbilitySystemComponent, RoleClass);
	}

	// 绑定血条控件
	if (UAuraUserWidget* UserWidget = Cast<UAuraUserWidget>(HealthBar->GetUserWidgetObject()))
	{
		// 血条控件设置控制器
		UserWidget->SetWidgetController(this);

		if (UAuraAttributeSet* AS = Cast<UAuraAttributeSet>(AttributeSet))
		{
			// 绑定属性变化委托
			AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(AS->GetHealthAttribute()).AddLambda(
				[this](const FOnAttributeChangeData& Data)
				{
					OnHealthChanged.Broadcast(Data.NewValue);
				}
			);

			AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(AS->GetMaxHealthAttribute()).AddLambda(
				[this](const FOnAttributeChangeData& Data)
				{
					OnMaxHealthChanged.Broadcast(Data.NewValue);
				}
			);

			// 广播初始化血量
			OnHealthChanged.Broadcast(AS->GetHealth());
			OnMaxHealthChanged.Broadcast(AS->GetMaxHealth());
		}
	}

	// 监听Effect_HitReact标签
	AbilitySystemComponent->RegisterGameplayTagEvent(FAuraGameplayTags::Get().Effect_HitReact).AddUObject(
		this,
		&AEnemyCharacter::OnHitReactTagChanged
	);
}

void AEnemyCharacter::InitAbilityActorInfo()
{
	Super::InitAbilityActorInfo();

	// 初始化ASC的相关Actor信息
	AbilitySystemComponent->InitAbilityActorInfo(this, this);

	Cast<UAuraAbilitySystemComponent>(AbilitySystemComponent)->SetAbilitySystemWorkInfo();

	// 在服务器通过GE初始属性
	if (HasAuthority())
	{
		InitDefaultAttributes();
	}
}

void AEnemyCharacter::InitDefaultAttributes() const
{
	UAuraAbilitySystemBPLibrary::InitDefaultAttributes(this, RoleClass, Level, AbilitySystemComponent);
}

// TODO: 这里不知道为啥调用了两次
void AEnemyCharacter::OnHitReactTagChanged(const FGameplayTag CallbackTag, const int32 NewCount)
{
	bHitReacting = NewCount > 0;
	// 如果被击中,角色最大速度为0
	GetCharacterMovement()->MaxWalkSpeed = bHitReacting ? 0.f : BaseWalkSpeed;
	// 设置AI控制器黑板键的值 
	if (AuraAIController && AuraAIController->GetBlackboardComponent())
	{
		AuraAIController->GetBlackboardComponent()->SetValueAsBool(TEXT("HitReacting"), bHitReacting);
	}
}
